﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Windows.Browser.Net;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;

namespace AgLux
{
    /// <summary>
    /// //
    /// </summary>

    public static class Parser
    {
        /// <summary>
        /// //
        /// </summary>

        /// <param name="source">
        /// //
        /// </param>

        /// <returns>
        /// //
        /// </returns>

        public static Course ParseCourseFromXml(string source)
        {
            string title = "Course";
            string description = "Description";
            List<Section> sections = new List<Section>();

            HttpWebRequest request = new BrowserHttpWebRequest(new Uri("Course/" + source + ".xml", UriKind.RelativeOrAbsolute));
            HttpWebResponse response = request.GetResponse();
            XmlReader reader = XmlReader.Create(new StreamReader(response.GetResponseStream()));

            while (reader.Read())
            {
                if (reader.IsStartElement() && reader.Depth == 0)
                {
                    if (reader.LocalName == "course")
                    {
                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "title")
                            {
                                title = reader.Value;
                            }

                            else if (reader.Name == "description")
                            {
                                description = reader.Value;
                            }
                        }
                    }
                }

                if (reader.IsStartElement() && reader.Depth == 1)
                {
                    if (reader.LocalName == "section")
                    {
                        string headline = "Section";

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "headline")
                            {
                                headline = reader.Value;
                            }
                        }

                        reader.MoveToElement();

                        sections.Add(ParseSectionFromXml(headline, reader.ReadSubtree()));
                    }
                }
            }

            response.Close();

            return new Course(title, description, new Tree(sections));
        }

        /// <summary>
        /// //
        /// </summary>

        /// <param name="header">
        /// //
        /// </param>

        /// <param name="reader">
        /// //
        /// </param>

        /// <returns>
        /// //
        /// </returns>

        private static Section ParseSectionFromXml(string header, XmlReader reader)
        {
            List<Component> components = new List<Component>();
            List<Section> subSections = new List<Section>();

            while (reader.Read())
            {
                if (reader.IsStartElement() && reader.Depth == 1)
                {
                    if (reader.LocalName == "text")
                    {
                        string background = "";
                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "background")
                            {
                                background = reader.Value;
                            }

                        }
                        reader.MoveToElement();
                        components.Add(ParseTextFromXml(reader.ReadSubtree(), background));
                    }

                    else if (reader.LocalName == "picture")
                    {
                        Filling filling = Filling.half;
                        string caption = "";

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "filling" && reader.Value == "full")
                            {
                                filling = Filling.full;
                            }

                            else if (reader.Name == "filling" && reader.Value == "oneFourth")
                            {
                                filling = Filling.oneFourth;
                            }

                            else if (reader.Name == "filling" && reader.Value == "threeFourth")
                            {
                                filling = Filling.threeFourth;
                            }

                            else if (reader.Name == "caption")
                            {
                                caption = reader.Value;
                            }
                        }

                        reader.MoveToElement();

                        components.Add(new Picture(reader.ReadElementContentAsString(), filling, caption));
                    }

                    else if (reader.LocalName == "audio")
                    {
                        string caption = "";
                        string transcript = "";

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "caption")
                            {
                                caption = reader.Value;
                            }
                            else if (reader.Name == "transcript")
                            {
                                transcript = reader.Value;
                            }
                        }

                        reader.MoveToElement();

                        components.Add(new Audio(reader.ReadElementContentAsString(),transcript, caption));
                    }
                    else if (reader.LocalName == "animation")
                    {
                        double height = 100;
                        bool autostart = false;
                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "height")
                            {
                                height = Convert.ToDouble(reader.Value);
                            }
                            else if (reader.Name == "autostart" && reader.Value == "true")
                            {
                                autostart = true;
                            }

                        }

                        reader.MoveToElement();
                        components.Add(new Animation(reader.ReadElementContentAsString(), height, autostart));

                    }

                    else if (reader.LocalName == "video")
                    {
                        Filling filling = Filling.half;
                        string caption = "";
                        string transcript = "";

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "filling" && reader.Value == "full")
                            {
                                filling = Filling.full;
                            }

                            else if (reader.Name == "filling" && reader.Value == "oneFourth")
                            {
                                filling = Filling.oneFourth;
                            }

                            else if (reader.Name == "filling" && reader.Value == "threeFourth")
                            {
                                filling = Filling.threeFourth;
                            }

                            else if (reader.Name == "caption")
                            {
                                caption = reader.Value;
                            }
                            else if (reader.Name == "transcript")
                            {
                                transcript = reader.Value;
                            }
                        }

                        reader.MoveToElement();

                        components.Add(new Video(reader.ReadElementContentAsString(),transcript, filling, caption));
                    }

                    else if (reader.LocalName == "link")
                    {
                        
                        string text = "Link";
                        

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "text" )
                            {
                                text = reader.Value;

                            }

                        }

                        reader.MoveToElement();

                        components.Add(new Link(reader.ReadElementContentAsString(), text));
                    }


                    else if (reader.LocalName == "task")
                    {
                        components.Add(ParseTaskFromXml(reader.ReadSubtree()));
                    }


                    else if (reader.LocalName == "section")
                    {
                        string subHeadline = "Section";

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "headline")
                            {
                                subHeadline = reader.Value;
                            }
                        }

                        reader.MoveToElement();

                        subSections.Add(ParseSectionFromXml(subHeadline, reader.ReadSubtree()));
                    }
                }
            }

            return new Section(header, components, subSections);
        }

        /// <summary>
        /// //
        /// </summary>

        /// <param name="reader">
        /// //
        /// </param>

        /// <returns>
        /// //
        /// </returns>

        private static Text ParseTextFromXml(XmlReader reader, string background)
        {
            List<Inline> content = new List<Inline>();
            
            while (reader.Read())
            {
                if (reader.IsStartElement() && reader.Depth == 1)
                {
                    if (reader.LocalName == "part")
                    {
                        Run part = new Run();
                        TextDecorations underline = new TextDecorations();
                        FontStyles italic = new FontStyles();
                        FontWeights bold = new FontWeights();
                        part.FontFamily = "Arial";
                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "font")
                            {
                                part.FontFamily = reader.Value;
                            }

                            else if (reader.Name == "size")
                            {
                                part.FontSize = Convert.ToInt32(reader.Value);
                            }
                            else if (reader.Name == "underline" && reader.Value == "true")
                            {
                                underline = TextDecorations.Underline;
                                part.TextDecorations = underline;

                            }
                            else if (reader.Name == "italic" && reader.Value == "true")
                            {
                                italic = FontStyles.Italic;
                                part.FontStyle = italic;

                            }

                            else if (reader.Name == "bold" && reader.Value == "true")
                            {
                                bold = FontWeights.Bold;
                                part.FontWeight = bold;

                            }

                            else if (reader.Name == "color")
                            {
                                if (reader.Value == "white")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.White);
                                }

                                else if (reader.Value == "gray")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Gray);
                                }

                                else if (reader.Value == "brown")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Brown);
                                }

                                else if (reader.Value == "red")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Red);
                                }

                                else if (reader.Value == "orange")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Orange);
                                }

                                else if (reader.Value == "yellow")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Yellow);
                                }

                                else if (reader.Value == "green")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Green);
                                }

                                else if (reader.Value == "blue")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Blue);
                                }

                                else if (reader.Value == "purple")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Purple);
                                }

                                else if (reader.Value == "magenta")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Magenta);
                                }

                                else if (reader.Value == "cyan")
                                {
                                    part.Foreground = new SolidColorBrush(Colors.Cyan);
                                }
                            }
                        }

                        reader.MoveToElement();

                        part.Text = reader.ReadElementContentAsString();
                        content.Add(part);
                    }

                    else if (reader.LocalName == "break")
                    {
                        content.Add(new LineBreak());
                    }
               /*     else if (reader.LocalName == "link")
                    {
                        Run link = new Run();
                        link.Text = reader.ReadElementContentAsString();
                        content.Add(link);

                    }*/
                }
            }

            return new Text(content, background);
        }

        /// <summary>
        /// //
        /// </summary>

        /// <param name="reader">
        /// //
        /// </param>

        /// <returns>
        /// //
        /// </returns>

        private static Task ParseTaskFromXml(XmlReader reader)
        {
            List<Question> questions = new List<Question>();

            while (reader.Read())
            {
                if (reader.IsStartElement() && reader.Depth == 1)
                {
                    if (reader.LocalName == "question")
                    {
                        string text = "Question";

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "text")
                            {
                                text = reader.Value;
                            }
                        }

                        reader.MoveToElement();

                        questions.Add(ParseQuestionFromXml(text, reader.ReadSubtree()));
                    }
                }
            }

            return new Task(questions);
        }

        /// <summary>
        /// //
        /// </summary>

        /// <param name="text">
        /// //
        /// </param>

        /// <param name="reader">
        /// //
        /// </param>

        /// <returns>
        /// //
        /// </returns>

        private static Question ParseQuestionFromXml(string text, XmlReader reader)
        {
            List<Answer> answers = new List<Answer>();

            while (reader.Read())
            {
                if (reader.IsStartElement() && reader.Depth == 1)
                {
                    if (reader.LocalName == "answer")
                    {
                        bool isCorrect = false;

                        while (reader.MoveToNextAttribute())
                        {
                            if (reader.Name == "correct" && reader.Value == "yes")
                            {
                                isCorrect = true;
                            }
                        }

                        reader.MoveToElement();

                        answers.Add(new Answer(reader.ReadElementContentAsString(), isCorrect));
                    }
                }
            }

            return new Question(text, answers);
        }
    }
}
